/*
 * MysqlConnection object defines the needed connection functions for the dbConnect MySQL driver
 * Copyright (C) 2002 Johnathan Ingram, jingram@rogueware.org
 *
 * This library is free software; you can redistribute it and/or
 *   modify it under the terms of the GNU Lesser General Public
 *   License as published by the Free Software Foundation; either
 *   version 2.1 of the License, or (at your option) any later version.
 *
 *   This library is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *   Lesser General Public License for more details.
 *
 *   You should have received a copy of the GNU Lesser General Public
 *   License along with this library; if not, write to the Free Software
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  US
 *
 * Notes:
 *  1)  The MySQL doc states: "All functions except mysql_real_connect() are currently thread-safe."
 *
 */

#ifndef __MYSQL_CONNECTION_H__
#define __MYSQL_CONNECTION_H__

#include <string>
#include <time.h>

#include "dbconnectTypes.h"
#include "baseConnection.h"
#include "baseException.h"
#include "simpleThreads.h"

#include <mysql.h>


#define MYSQL_DRIVERNAME    "MySQL"


using namespace std;


class MysqlQuery; // Need to be friends with.


class MysqlHandle : public BaseHandle
{
public:
   // MySQL Connection Handles;
   MYSQL    __mysql__;   
   void     *queryObject;             // Query Object bound to the connection

   // Constructor
   MysqlHandle() 
   : 
      queryObject(NULL) 
   { };  
};


class MysqlConnection : public BaseConnection
{

private: 
   struct MysqlOptions  // Options that can be set by the configuration file.
   {
      bool mysqlOptCompress;     // 'mysql_opt_compress' config file option under 'mysql' section.
      bool mysqlOptTransaction;  //  'mysql_opt_transaction' config file option under 'mysql' section.
      
      // Constructor
      MysqlOptions() 
      :
         mysqlOptCompress(true),
         mysqlOptTransaction(true)
      { }
   };


   // Collection types that can be freed within this object
   enum CollectionType
   {
      CONNECTION_HANDLES
   };

   // Thread mutexes
   SimpleThread_Mutex classMutex;

   // Structure storing the options for mysql from the dbconnect.cfg file.
   MysqlOptions _mysqlOptions;

   // Handles used by the driver
   DBULONG       _numHandles;
   MysqlHandle **_handles;

   /* Internal method to connect the handle to a MySQL database.
    *
    * @param handleIndex     Index to the connection handle that must be connected.
    */
   void 
   _mysqlConnect(
         int index);

   
   /* Internal method to disconnect the handle from a MySQL database.
    *
    * @param handleIndex     Index to the connection handle that must be disconnected.
    */
   void 
   _mysqlDisconnect(
         int index);


   /* Internal method to make sure the connection handle is still alive and reconnect if timed out.
    *
    * @param handleIndex     Index to the connection handle that must be pinged.
    */
   void 
   _mysqlPing(
         int index);


   /* Internal method to query MySQL. All query objects will use this.
    *
    * @param handleIndex     Index to the connection handle to use for the query.
    * @param sqlStatement    Sql statment to query against the database.
    */
   void 
   _mysqlQuery(
         int           index,
         const string& sqlStatement);


   /* Internal method to free internally allocated memory
    *
    * @param type    The type representing which value to deallocate.
    *
    */
   void _freeCollection(
         CollectionType type);


public:

   /* Constructor.
    *
    */
   MysqlConnection(
         int argc, 
         const char** argv);


   /* Destructor.
    *
    */
   ~MysqlConnection();


   /* Create connections to the database.
    *
    * @param username         Database username.
    * @param password         Password used for username.
    * @param databaseName     Name of the database connecting to.
    * @param host             Host the database resides on. Default "localhost"
    * @param maxConnections   Maximum number of connections the object can pool at any one time. Default 1
    * @param optParam1        Optional parameter that can be used by the driver.
    * @param optParam2        Optional parameter that can be used by the driver.
    *
    */
   void 
   connect(
         const string &username, 
         const string &password="", 
         const string &databaseName="", 
         const string &host="localhost", 
         int          maxConnections=1,
         int          minConnections=1,
         const string &optParam1="",
         const string &optParam2="");

   /* Destroy all connections to the database.
    *
    * @param timeout          Timeout in seconds to wait for connections to become idle. Default 120.
    */
   void 
   disconnect(
         time_t timeout=120);
     

   /* Obtain a connection that is attached to a query object.
    *
    * @param timeout     Interval in seconds that the function should block for before throwing an exception.
    *
    * @return            Returns a void pointer to a BaseQuery object. (The pointer needs to be type casted)
    */
   void*
   requestQueryConnection();
   

   /* release a connection that is attached to a query object.
    *
    * @param queryConnection   Pointer of the query connection to release.
    *
    */
   void
   releaseQueryConnection(
      void* queryObject);
  
  
   // Define all friend classes
   friend class MysqlQuery;
};


#endif
